﻿using Microsoft.AspNetCore.Http;
using Microsoft.ClearScript.V8;
using Newtonsoft.Json.Linq;
using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace EnterpriseInformation.Common
{
    public class HttpHelper : CustomLog
    {
        public HttpClient httpClient;
        public CookieContainer cookieContainer;

        static string Address;
        static DateTime? ChangeTime;

        public HttpHelper(string origin = "", string referer = "")
        {
            InitLog("全局");
            if (HttpHelper.ChangeTime == null)
            {
                HttpHelper.ChangeTime = DateTime.Now;
            }

            HttpClientHandler handler = null;

            JObject proxySetting = MyConfig.ProxySetting;

            bool startProxy = Convert.ToBoolean(proxySetting["start"].ToString()); 
            string orderid = proxySetting["orderid"].ToString(); 

            if (startProxy)
            {
                if (string.IsNullOrEmpty(HttpHelper.Address) || ((TimeSpan)(DateTime.Now - HttpHelper.ChangeTime)).TotalMinutes > 150)
                {
                    HttpHelper.ChangeTime = DateTime.Now;
                    //独享931536271104499
                    string api_url = $"http://dps.kdlapi.com/api/getdps?orderid={orderid}&num=1&pt=1&sep=1";
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(api_url);
                    request.Method = "GET";
                    request.Headers.Add("Accept-Encoding", "Gzip");  // 使用gzip压缩传输数据让访问更快
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        Log.Logger.Error("独享ip没有获取到");
                        //throw new Exception("独享ip没有获取到");
                    }
                    //string Address = string.Empty;
                    using (StreamReader reader = new StreamReader(new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)))
                    {
                        HttpHelper.Address = reader.ReadToEnd();
                    }
                }
                

                //隧道
                handler = new HttpClientHandler()
                {
                    UseProxy = true,
                    AutomaticDecompression = DecompressionMethods.GZip
                };

                WebProxy webProxy = new WebProxy();
                //webProxy.Address = new Uri(string.Format("{0}:{1}",
                //    proxySetting["url"].ToString(),
                //    proxySetting["port"].ToString()));

                //webProxy.Credentials = new NetworkCredential(
                //    proxySetting["username"].ToString(),
                //    proxySetting["password"].ToString());

                webProxy.Address = new Uri("http://" + HttpHelper.Address);
                //webProxy.Credentials = new NetworkCredential("wjhmiss","yt9xu0hi");

                handler.Proxy = webProxy;
                httpClient = new HttpClient(handler);
            }
            else
            {

                handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };

                httpClient = new HttpClient(handler);

            }


            httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36");
            httpClient.DefaultRequestHeaders.Add("Accept", @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");

            if (!string.IsNullOrEmpty(origin))
            {
                httpClient.DefaultRequestHeaders.Add("Origin", origin);
            }


            if (!string.IsNullOrEmpty(referer))
            {
                httpClient.DefaultRequestHeaders.Add("Referer", referer);
            }


            httpClient.DefaultRequestHeaders.Add("accept-encoding", "gzip, deflate, br");
            httpClient.DefaultRequestHeaders.Add("accept-language", "zh-CN,zh;q=0.8");


            httpClient.Timeout = TimeSpan.FromMilliseconds(30 * 1000);
         

            cookieContainer = new CookieContainer();

            handler.CookieContainer = cookieContainer;

        }

        public void GetHeaderStr(string url,string param)
        {
            string baseurl = "https://www.qcc.com";

            string headerPair = string.Empty;

            using (var engine = new V8ScriptEngine())
            {
                string script = EnterpriseInformation.Properties.Resources.sha_512;

                script = script + string.Format("var header_pair = encrypt(\"{0}\", \"{1}\");", url.Replace(baseurl, ""),
                    param.Replace("\r", "").Replace("\n", "").Replace(" ", "").Replace("\"", "\\\"").Replace("\\\\", "\\\\\\"));

                engine.Execute(script);

                headerPair = engine.Script.header_pair;


                if (headerPair.Contains('#'))
                {
                    string[] pp = headerPair.Split('#');
                    httpClient.DefaultRequestHeaders.Add(pp[0], pp[1]);
                }
            }
        }
         
        /// <summary>
        /// GET请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public Tuple<string, string> HttpGet(string url, Encoding encode = null)
        {

            if (encode == null)
            {
                encode = Encoding.GetEncoding("utf-8");
            }

            try
            {
                var response = httpClient.GetAsync(url).Result;
                string result = string.Empty;
                string cookie = string.Empty;

                if (response.IsSuccessStatusCode)
                {
                    Stream myResponseStream = response.Content.ReadAsStreamAsync().Result;
                    StreamReader myStreamReader = new StreamReader(myResponseStream, encode);
                    result = myStreamReader.ReadToEnd();
                    myStreamReader.Close();
                    myResponseStream.Close();
                }
                else if (response.StatusCode == HttpStatusCode.Moved || response.StatusCode == HttpStatusCode.MovedPermanently)
                {
                    string baseurl = response.Headers.GetValues("location").ToString().Trim();
                    string locationurl = baseurl.ToLower();
                    //HttpGet(locationurl);
                    Log.Logger.Error("HttpStatusCode.Moved :" + baseurl);

                }
                else
                {
                    return null;
                }
                var uri = new Uri(url);

                List<Cookie> cookies = cookieContainer.GetCookies(uri).Cast<Cookie>().ToList();

                List<string> listItem = new List<string>();

                foreach (Cookie cookieItem in cookies)
                {
                    listItem.Add(cookieItem.Name + "=" + cookieItem.Value);
                }


                return new Tuple<string, string>(string.Join("; ", listItem.ToArray()), result);
            }
            catch (Exception)
            {
                return null;
            }

        }



        public Tuple<string, string> HttpPostForm(string url, string param, Encoding encoding = null, string mediaType = "application/x-www-form-urlencoded")
        {
            try
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                HttpContent content = new StringContent(param, encoding, mediaType);

                var response = httpClient.PostAsync(url, content).Result;

                string result = string.Empty;
                string cookie = string.Empty;

                if (response.IsSuccessStatusCode)
                {
                    Stream myResponseStream = response.Content.ReadAsStreamAsync().Result;
                    StreamReader myStreamReader = new StreamReader(myResponseStream, encoding);
                    result = myStreamReader.ReadToEnd();
                    myStreamReader.Close();
                    myResponseStream.Close();
                }
                else
                {
                    return null;
                }
                var uri = new Uri(url);

                List<Cookie> cookies = cookieContainer.GetCookies(uri).Cast<Cookie>().ToList();

                List<string> listItem = new List<string>();

                foreach (Cookie cookieItem in cookies)
                {
                    listItem.Add(cookieItem.Name + "=" + cookieItem.Value);
                }


                return new Tuple<string, string>(string.Join("; ", listItem.ToArray()), result);
            }
            catch (Exception)
            {
                return null;
            }



        }



        public Tuple<string, string> HttpPostJson(string url, string param, Encoding encoding = null, string mediaType = "application/json")
        {
            try
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                GetHeaderStr( url,  param);
                HttpContent content = new StringContent(param, encoding, mediaType);

                var response = httpClient.PostAsync(url, content).Result;

                string result = string.Empty;
                string cookie = string.Empty;

                if (response.IsSuccessStatusCode)
                {
                    Stream myResponseStream = response.Content.ReadAsStreamAsync().Result;
                    StreamReader myStreamReader = new StreamReader(myResponseStream, encoding);
                    result = myStreamReader.ReadToEnd();
                    myStreamReader.Close();
                    myResponseStream.Close();
                }
                else
                {
                    return null;
                }
                var uri = new Uri(url);

                List<Cookie> cookies = cookieContainer.GetCookies(uri).Cast<Cookie>().ToList();

                List<string> listItem = new List<string>();

                foreach (Cookie cookieItem in cookies)
                {
                    listItem.Add(cookieItem.Name + "=" + cookieItem.Value);
                }


                return new Tuple<string, string>(string.Join("; ", listItem.ToArray()), result);
            }
            catch (Exception ex)
            {
                return null;
            }



        }

    }
}
